home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
COMM
/
PPL4P10A
/
TERM.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-02-20
|
13KB
|
439 lines
(**********************************************)
(* *)
(* TERM.PAS JAN 1995 *)
(* *)
(* TERM is a simple terminal emulator which *)
(* features ASCII, XMODEM, XMODEM-CRC, *)
(* XMODEM-1K, YMODEM, YMODEM-G, & ZMODEM *)
(* file transfer. *)
(* *)
(* Do NOT select YMODEM-G when using a null *)
(* modem cable unless you are certain that *)
(* RTS & CTS are reversed -- which is *)
(* usually not true. *)
(* *)
(* Remember that you cannot send or receive *)
(* binary files with ascii protocol - this *)
(* includes many word processor file formats *)
(* such as used by Wordstar. *)
(* *)
(**********************************************)
(* *)
(* This program is donated to the Public *)
(* Domain by MarshallSoft Computing, Inc. *)
(* It is provided as an example of the use *)
(* of the Personal Protocol Library. *)
(* *)
(**********************************************)
(* XMODEM & YMODEM variants
**
** Protocol OneKflag NCGbyte BatchFlag
**
** XMODEM False NAK False
** XMODEM-CRC False C False
** XMODEM-1K True C False
** YMODEM True C True
** YMODEM-G True G True
*)
{$I DEFINES.PAS}
program term;
{$IFDEF SCRIPTS}
uses config,si,hex_io,term_io,modem_io,xymodem,xypacket,amodem,crc16,crc32,zdate,zmodem,crt,PCL4P;
{$ELSE}
uses config,hex_io,term_io,modem_io,xymodem,xypacket,amodem,crc16,crt32,zdate,zmodem,crt,PCL4P;
{$ENDIF}
Var (* globals *)
ResetFlag: Boolean;
BaudText : String;
Port : Integer;
TxBufPtr : Pointer;
RxBufPtr : Pointer;
TxBufSeg : Integer;
RxBufSeg : Integer;
procedure MyHalt( Code : Integer );
var
RetCode : Integer;
begin
if Code < 0 then SayError( Code,'Halting' );
if ResetFlag then RetCode := SioDone(Port);
writeln('*** HALTING ***');
Halt;
end;
(* main program *)
const
NAK = $15;
ATTN_CHAR = $1a;
ABORT_CHAR = $18;
WrongBaud1 = 'Cannot recognize baud rate';
WrongBaud2 = 'Must be 300,600,1200,2400,4800,9600,19200,38400,57600, or 155200';
var (* globals *)
c : Char;
i : Integer;
TraceFlag : Boolean;
Filename : String;
ResultMsg : String;
Protocol : Char;
BaudCode : Integer;
RetCode : Integer;
TheByte : Char;
MenuMsg : String;
GetNameMsg: String;
Text40 : String;
OneKflag : Boolean;
NCGbyte : Byte;
BatchFlag : Boolean;
Flag : Boolean;
Version : Integer;
TermChar : Byte;
CharPace : Integer;
Timeout : Integer;
EchoFlag : Boolean;
Streaming : Boolean;
procedure ShowStatus(Attn:Byte;Text:String);
begin
WriteColMsg('COM'+chr($31+Port)+' '+BaudText+' '+Protocol+' [ ^'+chr($40+Attn)+' '+Text+' ]',1,29)
end;
procedure SetProtocol;
begin
WriteMsg('A)scii X)modem Y)modem Z)modem: ');
ReadMsg(ResultMsg,61,1);
c := UpCase(ResultMsg[1]);
case c of
'A': (* ASCII *)
begin
Protocol := 'A';
(* setup ascii parameters *)
TermChar := $18; (* CAN or control-X *)
CharPace := 1; (* 1 tic (5.5 ms) inter-byte delay *)
Timeout := 7; (* timeout after 7 seconds *)
EchoFlag := TRUE;(* local echo *)
WriteMsg('Protocol = ASCII');
end;
'X': (* XMODEM *)
begin
Protocol := 'X';
OneKflag := FALSE;
NCGbyte := NAK;
BatchFlag := FALSE;
WriteMsg('Protocol = XMODEM');
end;
'Y': (* YMODEM *)
begin
Protocol := 'Y';
OneKflag := TRUE;
NCGbyte := Ord('C');
BatchFlag := TRUE;
WriteMsg('Protocol = YMODEM');
end;
'Z': (* ZMODEM *)
begin
Protocol := 'Z';
WriteMsg('Protocol = ZMODEM');
end;
end; (* case *)
ShowStatus(ATTN_CHAR,'for Menu');
end;
Procedure ReceiveTheFile;
Var
Flag : Boolean;
begin
ShowStatus(ABORT_CHAR,'aborts');
case Protocol of
'A': (* ASCII *)
begin
(* Ascii *)
Filename := '';
if NOT FetchName(FileName) then exit;
Flag := RxAscii(Port,Filename,TermChar,Timeout,EchoFlag);
end;
'X':
begin
Filename := '';
Flag := XmodemRx(Port,Filename,NCGbyte);
end;
'Y':
begin
Filename := '';
Flag := YmodemRx(Port,Filename,NCGbyte)
end;
'Z':
begin
Flag := ZmodemRx(Port,Filename,Streaming);
end;
end; {case}
ShowStatus(ATTN_CHAR,'for Menu');
end; (* ReceiveTheFile *)
Procedure SendTheFile;
Var
Flag : Boolean;
begin
Filename := '';
if NOT FetchName(FileName) then exit;
ShowStatus(ABORT_CHAR,'aborts');
case Protocol of
'A': (* ASCII *)
Flag := TxAscii(Port,Filename,CharPace,TermChar,Timeout,EchoFlag);
'X': (* XMODEM *)
Flag := XmodemTx(Port,Filename,OneKflag);
'Y': (* YMODEM *)
Flag := YmodemTx(Port,Filename,OneKflag);
'Z': (* ZMODEM *)
Flag := ZmodemTx(Port,Filename,Streaming);
end {case};
ShowStatus(ATTN_CHAR,'for Menu');
end; (* SendTheFile *)
begin (* main program *)
TraceFlag := False;
TextMode(BW80);
ClrScr;
Window(1,1,80,24);
ResetFlag := FALSE;
Protocol := 'X';
OneKflag := FALSE;
NCGbyte := NAK;
BatchFlag := FALSE;
MenuMsg := 'Q)uit P)rotocol S)end R)eceive T)race: ';
(* fetch PORT # from command line *)
if ParamCount < 2 then
begin
writeln('USAGE: "TERM <port> <baudrate> {script}" ');
halt;
end;
Val( ParamStr(1),Port, RetCode );
if RetCode <> 0 then
begin
writeln('Port must be 1 to 16');
Halt;
end;
(* COM1 = 0, COM2 = 1, etc. *)
Port := Port - 1;
BaudText := ParamStr(2);
BaudCode := MatchBaud(BaudText);
if BaudCode < 0 then
begin
writeln(WrongBaud1);
writeln(WrongBaud2);
halt;
end;
(* streaming serial I/O at 19200 & less *)
if BaudCode < Baud38400 then Streaming := True
else Streaming := False;
(* patch up status message *)
if (Port<COM1) or (Port>COM16) then
begin
writeln('Port must be 1 to 16');
Halt
end;
(*** custom configuration: 4 port card
RetCode := SioIRQ(COM3,IRQ2);
RetCode := SioIRQ(COM4,IRQ2);
***)
(*** custom configuration: DigiBoard PC/8
RetCode := SioPorts(8,COM1,$140,DIGIBOARD);
RetCode := SioUART(Port,$100+8*Port) ;
if RetCode < 0 then MyHalt( RetCode );
RetCode := SioIRQ(Port,IRQ5) ;
if RetCode < 0 then MyHalt( RetCode );
***)
(*** custom configuration: BOCA board BB2016
RetCode := SioPorts(16,COM1,$107,BOCABOARD);
RetCode := SioUART(Port,$100+8*Port) ;
if RetCode < 0 then MyHalt( RetCode );
RetCode := SioIRQ(Port,IRQ5) ;
if RetCode < 0 then MyHalt( RetCode );
***)
(* setup 2K receive buffer *)
GetMem(RxBufPtr,2048+16);
RxBufSeg := Seg(RxBufPtr^) + ((Ofs(RxBufPtr^)+15) SHR 4);
RetCode := SioRxBuf(Port, RxBufSeg, SioBufCode);
if RetCode < 0 then MyHalt( RetCode );
(* setup 2K transmit buffer *)
GetMem(TxBufPtr,2048+16);
TxBufSeg := (Seg(TxBufPtr^)+1) + (Ofs(TxBufPtr^) SHR 4);
RetCode := SioTxBuf(Port, TxBufSeg, SioBufCode);
if RetCode < 0 then MyHalt( RetCode );
(* reset port *)
RetCode := SioReset(Port,BaudCode);
(* if error then try one more time *)
if RetCode <> 0 then RetCode := SioReset(Port,BaudCode);
(* Was port reset ? *)
if RetCode <> 0 then
begin
writeln('Cannot reset COM',Port+1);
MyHalt( RetCode );
end;
(* Port successfully reset *)
ResetFlag := TRUE;
ClrScr;
(* show logon message *)
WriteLn(' -- TERM 02/20/95 --');
WriteLn;
Write('TX interrupts: ');
if SioInfo('I') = 0 then WriteLn('NO')
else WriteLn('YES');
Version := SioInfo('V');
WriteLn(' Library: ',Version SHR 4,'.',15 AND Version);
(* specify parity, # stop bits, and word length for port *)
RetCode := SioParms(Port, NoParity, OneStopBit, WordLength8);
if RetCode < 0 then MyHalt( RetCode );
RetCode := SioRxFlush(Port);
if RetCode < 0 then MyHalt( RetCode );
Write(' Flow control: ');
{$IFDEF RTS_CTS_CONTROL}
(* enable RTS/CTS flow control *)
RetCode := SioFlow(Port,10*18);
WriteLn('YES');
{$ELSE}
WriteLn('NO');
{$ENDIF}
(* set FIFO level if have INS16550 *)
RetCode := SioFIFO(Port, LEVEL_8);
Write(' 16550 UART: ');
if RetCode > 0 then WriteLn('YES')
else WriteLn('NO');
WriteLn;
(* set DTR & RTS *)
RetCode := SioDTR(Port,SetPort);
RetCode := SioRTS(Port,SetPort);
{$IFDEF AT_COMMAND_SET}
Write('Waiting for DSR');
repeat
if SioBrkKey OR KeyPressed then
begin
Write('Aborted by user...');
RetCode := SioDone(Port);
Halt
end;
Write('.');
SioDelay(18);
until (SioDSR(Port)>0);
WriteLn;
{$ENDIF}
{$IFDEF RTS_CTS_CONTROL}
Write('Waiting for CTS');
repeat
if SioBrkKey OR KeyPressed then
begin
Write('Aborted by user...');
RetCode := SioDone(Port);
Halt
end;
Write('.');
SioDelay(18);
until (SioCTS(Port)>0);
WriteLn;
{$ENDIF}
{$IFDEF AT_COMMAND_SET}
(* send initialization string to modem *)
Flag := ModemSendTo(Port,5,'!!AT E1 S7=60 S11=60 V1 X1 Q0!');
if ModemWaitFor(Port,100,FALSE,'OK') <> chr(0) then
begin
writeln; writeln('MODEM ready');
end
else writeln('WARNING: Expected OK not received');
{$ENDIF}
{$IFDEF SCRIPTS}
if ParamCount = 3 then
begin
RetCode := Script(Port,ParamStr(3), False );
if RetCode < 0 then SaySiErr(RetCode);
end;
{$ENDIF}
(* begin terminal loop *)
writeln;
writeln('Enter terminal loop:');
ShowStatus(ATTN_CHAR,'for Menu');
SetMsgCol(30);
LowVideo;
while TRUE do
begin (* while TRUE *)
(* did user press Ctrl-BREAK ? *)
if SioBrkKey then
begin
writeln('User typed Ctl-BREAK');
RetCode := SioDone(Port);
Halt;
end;
(* BREAK signal ? *)
if SioBrkSig(Port,DETECT) > 0 then WriteMsg('BREAK detected');
(* anything incoming over serial port ? *)
RetCode := SioGetc(Port,1);
if RetCode < -1 then MyHalt( RetCode );
if RetCode > -1 then write(chr(RetCode));
(* has user pressed a key ? *)
if KeyPressed then
begin (* keypressed *)
(* read keyboard *)
TheByte := ReadKey;
case TheByte of
chr($02):
begin
(* send a BREAK *)
WriteMsg('Sending BREAK');
RetCode := SioBrkSig(Port,ASSERT);
SioDelay(5);
RetCode := SioBrkSig(Port,CANCEL);
end;
chr(ATTN_CHAR):
begin
WriteMsg(MenuMsg);
ResultMsg[1] := chr(0);
ReadMsg(ResultMsg,68,1);
c := UpCase(ResultMsg[1]);
case c of
'Q': (* QUIT *)
begin
WriteLn;
WriteLn('TERMINATING: User pressed <ESC>');
RetCode := SioDone(Port);
Halt;
end;
'T': (* Trace *)
begin
TraceFlag := NOT TraceFlag;
MsgEcho(TraceFlag);
WriteBoolMsg('Trace is ',TraceFlag);
end;
'P': SetProtocol;
'S': SendTheFile;
'R': ReceiveTheFile;
chr($0): {null}
else WriteMsg('Bad response');
end {case}
end (* ESC *)
else (* case *)
begin
(* send out over serial line *)
RetCode := SioPutc(Port, TheByte );
if RetCode < 0 then MyHalt( RetCode );
end
end {case}
end (* keypressed *)
end (* while TRUE *)
end.